package com.controller;

import com.pojo.SysRight;
import com.pojo.Vo.SysUserVo;
import com.service.SysRightService;
import com.service.UserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Controller
public class IndexController {
    @Autowired
    UserService userService;

    @Autowired
    SysRightService sysRightService;

    @Resource
    StringRedisTemplate stringRedisTemplate;

    /**
     * 跳转到登录页
     * @return
     */
    @RequestMapping("/")
    public Object login(){
        return "login";
    }

    /**
     * 登录验证
     * @param usrName  用户名
     * @param usrPassword  密码
     * @param model
     * @param session
     * @return
     */
    @RequestMapping("/doLogin")
    public Object list(String usrName, String usrPassword,Boolean remeberMe,Model model, HttpSession session){
//        SysUserVo user= userService.login(usrName, usrPassword);
//        if (user==null){
//            model.addAttribute("message","账号或密码错误");
//            return "login";
//        }else {
//            if (remeberMe){
//                stringRedisTemplate.opsForValue().set("loginUser", JSON.toJSONString(user));
//            }
//            session.setAttribute("loginUser", user);
//            return "main";
//        }

        String errStr=stringRedisTemplate.opsForValue().get(usrName+"errorCount:");
        Integer errCount=errStr!=null?Integer.parseInt(errStr):1;
        if (errCount>=5){
            //设置过期时间
            stringRedisTemplate.expire(usrName+"errorCount:",24, TimeUnit.HOURS);
            model.addAttribute("message","密码错误次数过多，请24小时后再试");
            return "login";
        }
        //根据用户名和密码创建凭证
        UsernamePasswordToken usernamePasswordToken=new UsernamePasswordToken(usrName,usrPassword,remeberMe!=null);
        try {
            Subject subject= SecurityUtils.getSubject();
            //通过subject将token交给securityManager 如果认证通过则返回认证对象，否则抛出异常
            subject.login(usernamePasswordToken);
            //获取认证通过的对象
            SysUserVo sysUser=(SysUserVo)subject.getPrincipal();

            //获取用户拥有的权限
            List<SysRight> rightList=sysRightService.getListByRoleId(sysUser.getUsrRoleId());
            sysUser.getRole().setRights(rightList);

            //将认证通过的对象放到session中
            session.setAttribute("loginUser", sysUser);
        }catch (UnknownAccountException e){
            model.addAttribute("message","账号不存在!");
            return "login";
        }catch (LockedAccountException e){
            model.addAttribute("message","账号被禁用!");
            return "login";
        }catch (AuthenticationException e){
            //每次错误,次数加1
            stringRedisTemplate.opsForValue().increment(usrName+"errorCount:",1);
            model.addAttribute("message","账号或密码错误!");
            return "login";
        }
        //登录成功则清理错误次数
        stringRedisTemplate.delete(usrName+"errorCount:");
        //清除当前登录用户的权限缓存  静态权限刷新
//        DefaultWebSecurityManager defaultWebSecurityManager= (DefaultWebSecurityManager) SecurityUtils.getSecurityManager();
//        Collection<Realm> realms=defaultWebSecurityManager.getRealms();
//        if (realms!=null && !realms.isEmpty()){
//            Iterator var3=realms.iterator();
//            while (var3.hasNext()){
//                Realm realm=(Realm)var3.next();
//                if (realm instanceof CustomRealm){
//                    CustomRealm tempReaml=(CustomRealm)realm;
//                    tempReaml.clearMyCachedAuthorizationInfo();
//                }
//            }
//        }
        return "main";
    }

    /**
     * 退出
     * @param session
     * @return
     */
    @RequestMapping("/logout")
    public Object logout(HttpSession session){
        session.removeAttribute("loginUser");
        return "login";
    }

    @RequestMapping("/403")
    public String authError(){return "403";}
}
